﻿using Creator.Core.Base;
using PropertyTools.Wpf;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace Creator.Helpers.ControlHelper
{
    public class ControlFactory : PropertyGridControlFactory
    {
        public static bool IsList(Type type)
        {
            if (null == type)
                throw new ArgumentNullException("type");

            if (typeof(System.Collections.IList).IsAssignableFrom(type))
                return true;
            foreach (var it in type.GetInterfaces())
                if (it.IsGenericType && typeof(IList<>) == it.GetGenericTypeDefinition())
                    return true;
            return false;
        }


        public override FrameworkElement CreateControl(PropertyItem pi, PropertyControlFactoryOptions options)
        {
            var typeCode = Type.GetTypeCode(pi.ActualPropertyType);

            if (typeCode == TypeCode.Object && pi.ActualPropertyType.IsClass)
            { 
                var isList = IsList(pi.ActualPropertyType); //是否为集合 
                var isComponent = typeof(IComponent).IsAssignableFrom(pi.ActualPropertyType);  
                if (isComponent)
                {
                    if (!(pi.BaseInstance is IComponent fatherCompoent))
                    {
                        return GetErrorTextBlock("组件(Component)只能是组件的属性。");
                    }
                    //组件类
                    Button btn = new Button()
                    {
                        HorizontalAlignment = HorizontalAlignment.Left, 
                        Foreground = new SolidColorBrush(Colors.Black), 
                    }; 
                    var compoent = GetValue(pi.BaseInstance, pi.PropertyName);
                    btn.Content = compoent != null ? compoent.ToString() : "单击选择组件。";
                    btn.Click += (s, e) =>
                    {
                        var result = fatherCompoent.OnBehaviourClick?.Invoke(fatherCompoent, pi.ActualPropertyType);  
                        SetValue(pi.BaseInstance, pi.PropertyName, result);
                        if (result != null)
                        {
                            btn.Content = result.ToString();
                        } 
                    };
                    return btn;
                }
                else
                {
                    try
                    {
                        //普通类的嵌套
                        PropertyGrid pg = new PropertyGrid();
                        //如果有无参构造 ，会报错
                        var value = GetValue(pi.BaseInstance,pi.PropertyName) ?? Activator.CreateInstance(pi.ActualPropertyType);
                        pg.SelectedObject = value;
                        pg.ControlFactory = new ControlFactory();
                        return pg;
                    }
                    catch (Exception ex)
                    { 
                        return GetErrorTextBlock(ex.Message);
                    }
              
                } 
            } 
            return base.CreateControl(pi, options);
        }

        private object GetValue(object target, string propertyName)
        {
            try
            {
                if (target == null) return null;
                return target.GetType()
                 .GetProperty(propertyName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
                 .GetValue(target);
            }
            catch (Exception)
            {

                return null;
            }
        }

        private void SetValue(object target, string propertyName, object value)
        {
            try
            {
                if (target == null) return;
                 target.GetType()
                 .GetProperty(propertyName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
                 .SetValue(target,value);
            }
            catch (Exception)
            {
                 
            }
        }
        /// <summary>
        /// 获取错误错误文本
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        private TextBlock GetErrorTextBlock(string msg)
        {
            TextBlock tb = new TextBlock();
            tb.Text = msg;
            tb.Foreground = new SolidColorBrush(Colors.Red);
            return tb;
        }

        private FrameworkElement CreatePreson(PropertyItem pi, PropertyControlFactoryOptions options)
        {

            return null;
        }
    }
}
